using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UMC.Data;
using UMC.Net;
using UMC.WorkFlow.Entities;

namespace UMC.WorkFlow.Subassembly
{
    [UIDesign(Name = "追加字典", Explain = "通过SQL或Http获取流程字典")]
    public class DictionaryRegister : UMC.WorkFlow.Responder
    {

        [Design(Caption = "API字典", Explain = "用Http API的方式获取表单字典，返回格式请参考文档")]
        public GetSetting Http { get; set; }
        protected override void OnRespond(UMC.WorkFlow.InstanceEvent taskEvent)
        {
            if (this.SQL != null && String.IsNullOrEmpty(this.SQL.SqlText) == false)
                taskEvent.OnBeginProcess += SQLProcess;

            if (this.Http != null && String.IsNullOrEmpty(this.Http.Url) == false)
                taskEvent.OnBeginProcess += HttpProcess;
        }

        [DesignAttribute(Caption = "字典的前缀", Explain = "如果前缀为“UI”，则会保存到表单中")]
        public string PrefixName { get; set; }


        [Design(Caption = "字典脚本", Explain = "把第一行记录，采用对典追加表单参数中")]
        public SqlStatusSetting SQL { get; set; }
        string sonsorShapeId = "ALL";
        [DesignAttribute(Caption = "触发流程结点", ArgumentType = ArgumentType.Shape)]
        public string ShapeId
        {
            get
            {
                return sonsorShapeId;
            }
            set
            {
                sonsorShapeId = value;
            }
        }

        protected override void WriteProperty(System.IO.TextWriter writer)
        {
            writer.Write(',');
            JSON.Serialize("ShapeId", this.ShapeId, writer);
            if (String.IsNullOrEmpty(PrefixName) == false)
            {
                writer.Write(',');
                JSON.Serialize("PrefixName", this.PrefixName, writer);
            }

            if (this.SQL != null)
            {
                writer.Write(',');
                JSON.Serialize("SQL", this.SQL, writer);
            }
            if (this.Http != null)
            {
                writer.Write(',');
                JSON.Serialize("Http", this.Http, writer);
            }


            base.WriteProperty(writer);
        }
        public override Func<object> GetInstance(string prototypeName)
        {
            switch (prototypeName)
            {
                case "SQL":
                    return () => new SqlStatusSetting();
                case "Http":
                    return () => new GetSetting();
                default:
                    return base.GetInstance(prototypeName);

            }
        }
        public override void Read(string key, object value)
        {
            switch (key)
            {
                case "ShapeId":
                    this.ShapeId = value as string;
                    break;
                case "PrefixName":
                    this.PrefixName = value as string;
                    break;
                case "SQL":
                    this.SQL = value as SqlStatusSetting;
                    break;
                case "Http":
                    this.Http = value as GetSetting;
                    break;

            }
            base.Read(key, value);
        }

        void SQLProcess(UMC.WorkFlow.TaskInstance task, UMC.WorkFlow.InstanceEventArgs e)
        {
            if (String.IsNullOrEmpty(sonsorShapeId) == false && String.Equals(sonsorShapeId, "ALL", StringComparison.CurrentCultureIgnoreCase) == false)
            {
                if (e.Shape.Id.StartsWith(sonsorShapeId) == false)
                {
                    return;
                }
            }


            var es = Utility.Enum(SQL.CommandType);
            for (int i = 0; i < es.Length; i++)
            {
                if (es[i] == e.CommandType)
                {
                    SQLDIC(e.Runtime.Items, task.InstanceId);
                    break;

                }
            }
        }
        void SQLDIC(System.Collections.IDictionary item, ulong InstanceId)
        {
            if (this.SQL != null)
            {
                // System.Collections.IDictionary dic = e.Runtime.Items;

                System.Collections.IDictionary table = SubassemblyHelper.ExecuteDictionary(SQL, item);
                if (table != null)
                {
                    string str = PrefixName;
                    if (String.IsNullOrEmpty(PrefixName) == false)
                    {
                        if (PrefixName.EndsWith(".") == false)
                        {
                            str += ".";
                        }
                    }
                    else
                    {
                        str = "Register.";
                    }
                    var enumer = table.GetEnumerator();
                    while (enumer.MoveNext())
                    {
                        item[String.Format("{0}{1}", str, enumer.Key)] = enumer.Value;
                    }
                    if (String.Equals(str, "UI."))
                    {
                        Dic(table, InstanceId);
                    }
                }
            }

        }
        void Dic(IDictionary UIData, ulong InstanceId)
        {
            if (UIData.Count > 0)
            {
                var keys = new List<String>();
                var uidata = new List<TaskData>();
                var emUI = UIData.GetEnumerator();
                while (emUI.MoveNext())
                {
                    var key = emUI.Key as string;

                    uidata.Add(new TaskData
                    {
                        DataIndex = -1,
                        DataName = key,
                        DataValue = emUI.Value as string,
                        DataText = emUI.Value as string,
                        InstanceId = InstanceId
                    });
                    keys.Add(key);
                }
                if (keys.Count > 0)
                {

                    keys.RemoveAll(n => uidata.Exists(t => t.DataName == n));
                    foreach (var n in keys)
                    {
                        Utility.Each(DataFactory.Instance().TaskData(InstanceId, n), r => DataFactory.Instance().Delete(r));
                    }
                    foreach (var d in uidata)
                    {
                        DataFactory.Instance().Put(d);
                    }

                    // var sqler = UMC.WorkFlow.TaskRuntime.Database.ObjectEntity<TaskData>();
                    // sqler.Where.And().Equal(new TaskData { InstanceId = InstanceId }).And().In(new TaskData { DataName = keys[0] }, keys.ToArray())
                    //     .Entities.Delete();
                    // sqler.Insert(uidata.ToArray());
                }
            }
        }
        void HttpProcess(UMC.WorkFlow.TaskInstance task, UMC.WorkFlow.InstanceEventArgs e)
        {
            if (String.IsNullOrEmpty(sonsorShapeId) == false && String.Equals(sonsorShapeId, "ALL", StringComparison.CurrentCultureIgnoreCase) == false)
            {
                if (e.Shape.Id.StartsWith(sonsorShapeId) == false)
                {
                    return;
                }
            }

            var es = Utility.Enum(Http.CommandType);
            for (int i = 0; i < es.Length; i++)
            {
                if (es[i] == e.CommandType)
                {
                    var curl = new StringBuilder();
                    var items = e.Runtime.Items;
                    var enumer = items.GetEnumerator();
                    while (enumer.MoveNext())
                    {
                        if (curl.Length > 0)
                        {
                            curl.Append(',');
                        }
                        curl.Append(Uri.EscapeDataString(enumer.Key as string));
                        curl.Append('=');
                        curl.Append(Uri.EscapeDataString((enumer.Value as string) ?? ""));

                    }

                    var webr = new Uri(Http.Url).WebRequest();
                    webr.ContentType = "application/x-www-form-urlencoded";
                    var data = JSON.Deserialize(webr.Post(curl.ToString()).ReadAsString()) as Hashtable;
                    if (data != null)
                    {
                        if (String.Equals(data["success"] as string, "true"))
                        {
                            var table = data["data"] as Hashtable;
                            if (table != null)
                            {
                                string str = PrefixName;
                                if (String.IsNullOrEmpty(PrefixName) == false)
                                {
                                    if (PrefixName.EndsWith(".") == false)
                                    {
                                        str += ".";
                                    }
                                }
                                else
                                {
                                    str = "Register.";
                                }
                                enumer = table.GetEnumerator();
                                while (enumer.MoveNext())
                                {
                                    items[String.Format("{0}{1}", str, enumer.Key)] = enumer.Value;
                                }
                                if (String.Equals(str, "UI."))
                                {
                                    Dic(table, task.InstanceId);
                                }

                            }
                        }
                        else if (data.ContainsKey("msg"))
                        {

                            throw new UMC.WorkFlow.TaskMessageException(data["msg"] as string);
                        }
                        else
                        {
                            throw new UMC.WorkFlow.TaskMessageException(String.Format("{0}服务组件获取Http返回格式不正确", this.Text));

                        }

                    }
                    else
                    {
                        throw new UMC.WorkFlow.TaskMessageException(String.Format("{0}服务组件获取Http返回格式不正确", this.Text));
                    }

                    //var dic = TaskRuntime.Current.Items.GetEnumerator();
                    break;

                }
            }
        }
    }
}
